OAuth 2.0
4つの登場人物
用語
書籍
2022/10/15
1.0がモノリスな感じだったのに比較して、2.0はモジュラーな感じになった
2012年頃?
委譲プロトコル?
と言われても全くわからんが
リソースを管理している誰か(リソース所有者)がソフトウェア·アプリケーションに所有者自身のなりすましをさせるのではなく、リソース所有者の代わりとして対象のリソースへのアクセスを許可するための手段
何を言っているのかわからん
2つのサービスがあるとする
S3のようなストレージサービス
印刷サービスP
これら2つは別の企業が管理しているサービス
これら2つを利用しているuser X
Pは、APIを介してS3にアクセスすることができる
Xから見れば、この2つが連携しているので便利
しかし、これを実現するためには、Pに「XのS3のパスワード」を教えてないといけない
めっちゃ安易に考えれば、「パスワードを共有する」になる
両方とも同じ企業が作っていたり、1つの企業内の話であれば、責任を持ってパスワード管理をさせればいい
これはセキュリティ的に良くない
ここでOAuthをつかう
Pに、S3へのアクセス権を委譲し、パスワードを教えなくても連携させることができる
OAuth以外での同じ問題の実現方法
パスワードを共有する
clientとresourceを同じ企業内で使っているとかならさほど問題は起きない
責任を持ってpassを保存すればいい
元々resouceのpassを持っているようなものだし
第三者のclientには応用できない
こうした場合、resourceにアクセスしてきたものが、実際のuserなのか、clientなのか区別がつかないという問題もある
随時?userへの問い合わせをする
clientが、resourceにアクセスする必要が出てきた時に、userにpassを聞く
clientはそれを使って、resourceにアクセスする
ただ、毎回聞くのもだるいので、clientはそのpassを保存する
結局clientにpassを教えているmrsekut.icon
clientがそれを漏洩させたら終わる
こうした場合、resourceにアクセスしてきたものが、実際のuserなのか、clientなのか区別がつかないという問題もある
権限が全て渡されるので、clienは削除も追記もなんでもし放題になる
resource側がそれを判別して制限することができない
resourceのサービスが、clientに開発者キーを渡す
e.g. Twitterが、黒歴史クリーナーに開発者のキーを渡す
Xのpassをclientに教えなくて済む
userがXであるとかYであるとか関係なく何でもし放題
Xとしてツイートすることも、Yとして削除することもできる
2つのサービスが同じ企業が管理しているならありうる
resouceが2種類のpassを発行する
clientに教える用のpassを発行する
OAuthとだいたい同じことができる
uesrは2種類のpassを覚えておく必要がある
Twitter連携のやつもこれか
https://gyazo.com/eaa2804a434b4b34161915d7829bf594
黒歴史クリーナーの管理者に、自分のTwitterのパスワードを教えずに、自分のツイートの操作をさせることができる
これは、Twitterが、黒歴史クリーナーにツイート削除の権限を委譲しているから
userが干渉しない
clientとauth serverらが直接やり取りする
OAuth
クライアントが、ユーザに対して「権限を委譲することのリクエスト」をできるようにする仕組み
トークンの取得方法と、トークンの使用方法に関する仕様
システムをまたいで認可を行える
委譲プロトコル
良い点
ユーザーは、アクセストークンに触れない
覚える必要も管理する必要もない
クライアントには過不足ない権限を与えられる
言うて、許した権限程度のものだからそこまで問題にならない?
パスワードなどが直接流出するわけではない
ユーザーとクライアントが区別される
一度トークンを取得できれば、ユーザーがいなくても、やり取りし続けられる
Basic認証やCookieとは異なる点
認証に用いられる情報
e.g. ID、password
OAuthは、HTTPS上でしか使えない
認可サーバーは誰が管理してるの?
認可サーバーはなぜ複数種類存在するの?
それとも世界に1種類しかないの?
認可サーバーは何をやっているの
全てのクライアントとユーザのクレデンシャルとトークンを管理している?
ここが攻撃されたら結構やばい?
https://www.youtube.com/watch?v=PKPj_MmLq5E
たぶん一例mrsekut.icon
OAuthの話
この例がどこまで一般的な状況なのかわからん #?? 前提
認可サーバーと、Protected Resourcesは秘密鍵を共有している
認可サーバーが、トークンの署名を行う
algの暗号化アルゴリズムを使って署名する
code:例.js
const accessToke = jose.jws.JWS.sign(
header.alg,
JSON.stringify(header),
JSON.stringify(payload),
new Buffer(sharedTokenSecret).toString('hex')
)
これによって、xxx.xxx.xxxの形式のtokenができる
Protected Resourceが検証する
code:例.js
const verified = jose.jws.JWS.verify(
token,
new Buffer(sharedTokenSecret).toString('hex'),
);
if (verified) {
// 検証が成功しているので、JWTの中身を取り出したりできる
}
前提
認可サーバーは、公開鍵と秘密鍵を持っている
Protected Resourcesは、公開鍵を持っている
認可サーバーで署名
code:Js
const accessToken = jose.jws.JWS.sign(
header.alg,
JSON.stringify(header),
JSON.stringify(payload),
privateKey
);
Protected Resourceが検証する
code:例.js
const verified = jose.jws.JWS.verify(
token,
publicKey,
);
if (verified) {
// 検証が成功しているので、JWTの中身を取り出したりできる
}